<template>
  <div id="terminalContainer" class="terminal-wrapper"
    style="height: 100vh; width: 100vw;">
    <q-btn class="release-vm-btn"
      round color="primary" @click="releaseVM">释放</q-btn>
  </div>
</template>

<script>
import { Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import '@xterm/xterm/css/xterm.css';

export default {
  name: 'OnlineTestTerminal',
  props: {},
  data() {
    return {
      term: null,
      fitAddon: new FitAddon(),
      ws: null,
      vmReleased: false,
      pingTimer: null,
    };
  },
  meta: {
    title: '人工智能互联互通开源评测平台',
  },
  computed: {
    env() {
      return process.env.env;
    },
  },
  watch: {
    $route(to, from) {
      if (to.params.vm !== from.params.vm) {
        this.connectToVM();
      }
    },
  },
  mounted() {
    this.connectToVM();
  },
  methods: {
    connectToVM() {
      if (this.term) {
        this.term.dispose();
      }

      // 获取localStorage中的信息，以确保此页面是从云资源列表页面跳转过来的
      const startTime = localStorage.getItem('fromOnlineTest');

      if (!startTime || (Date.now() - startTime > 1000 * 60)) {
        this.$q.dialog({
          title: '提示',
          message: '请从云资源打开。页面将自动跳转！',
          ok: '确定',
          cancel: false,
          persistent: true,
        }).onOk(() => {
          this.$router.push('/test');
        });

        return;
      }

      this.$q.loading.show({
        message: '正在准备云资源...',
      });

      this.setToFullScreen();

      // 创建Terminal实例
      this.term = new Terminal({
        cursorBlink: true,
        scrollOnUserInput: true,
      });

      this.term.loadAddon(this.fitAddon);

      // 将Terminal附加到DOM元素
      this.term.open(document.getElementById('terminalContainer'));
      this.fitAddon.fit();

      this.postRequest('/cloud/vm/connect', {
        vm: this.$route.params.vm,
      }).then((res) => {
        const { uuid } = res?.data || {};

        // console.log('got uuid:', uuid);

        if (uuid) {
          // production环境下使用wss，开发环境下使用ws
          const protocol = (this.env === 'development') ? 'ws' : 'wss';
          const host = (this.env === 'development') ? 'localhost:8000' : window.location.host;
          const wsUrl = `${protocol}://${host}/cloud/vm/connect/${uuid}`;

          this.ws = new WebSocket(wsUrl);

          this.ws.onmessage = (event) => {
            if (event.data === 'pong') {
              return;
            }

            if (event.data === 'exit' && !this.vmReleased) {
              this.$q.dialog({
                title: '提示',
                message: '连接中断，窗口即将关闭！',
                persistent: true,
                ok: '确定',
                cancel: false,
              }).onOk(() => {
                window.close();
              });

              return;
            }

            if (event.data === 'release') {
              this.vmReleased = true;
              this.$q.dialog({
                title: '提示',
                message: '长时间未操作或资源过期，云资源已释放，窗口即将关闭！',
                persistent: true,
                ok: '确定',
                cancel: false,
              }).onOk(() => {
                window.close();
              });

              return;
            }

            if (event.data === '[[cmd]]: connected') {
              // 添加容器尺寸
              this.resizeTerm();

              return;
            }

            this.$q.loading.hide();

            this.term.write(event.data);
          };

          this.ws.onopen = () => {
            this.term.write('欢迎使用互联互通云平台!\r\n\r\n');

            this.$q.loading.show({
              message: '正在连接云资源...',
            });

            this.pingTimer = setInterval(() => {
              this.ws.send('ping');
            }, 1000 * 60);

            this.observeResize();
          };

          this.term.onData((data) => {
            // 处理用户输入
            this.ws.send(data);
          });
        } else {
          this.$q.notify({
            message: '连接失败',
            color: 'negative',
            position: 'top',
            timeout: 2000,
          });
        }
      });
    },
    setToFullScreen() {
      document.documentElement.style.overflow = 'hidden';
    },
    releaseVM() {
      this.$q.dialog({
        title: '释放云资源',
        message: '确定要释放云资源吗？释放后将无法恢复。',
        persistent: true,
        ok: '确定',
        cancel: '取消',
      }).onOk(() => {
        this.postRequest('/cloud/vm/release', {
          vm: this.$route.params.vm,
        }).then(() => {
          window.close();
        });
      });
    },
    resizeTerm() {
      const height = document.body.clientHeight;
      const width = document.body.clientWidth;
      const rows = parseInt(height / 18, 10); // 18是字体高度,根据需要自己修改
      const cols = parseInt(width / 9, 10);

      // console.log('resizeTerm:', rows, cols);

      if (this.ws) {
        // 通过WebSocket发送尺寸信息到后端
        this.ws.send(`[[resize]]: ${rows}x${cols}`);
      }

      if (this.fitAddon) {
        this.fitAddon.fit();
      }

      if (this.term) {
        // this.term.resize(cols, rows);
        this.term.scrollToBottom(); // 确保滚动到底部
      }
    },
    observeResize() {
      const container = document.getElementById('terminalContainer');
      const observer = new ResizeObserver(() => {
        this.resizeTerm();
      });

      observer.observe(container);
      this.$once('hook:beforeDestroy', () => observer.disconnect());
    },
  },
  beforeDestroy() {
    if (this.term) {
      this.term.dispose();
    }

    if (this.ws) {
      this.ws.close();
    }

    if (this.pingTimer) {
      clearInterval(this.pingTimer);
    }
  },
};
</script>

<style lang="scss" scoped>
.terminal-wrapper {
  :deep(.terminal) {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
  }

  :deep(.xterm-viewport) {
    overflow: hidden;
  }
}
.release-vm-btn {
  position: fixed;
  bottom: 32px;
  right: 32px;

  opacity: 0.5;
  border-radius: 50%;

  z-index: 1;
}
</style>

<style lang="scss">
.xterm-screen {
  height: 100% !important;
  width: 100% !important;

  .xterm-rows {
    &>div {
      width: 100% !important;
    }
  }
}
</style>
